fix(windows-ime): 静态链接 CRT 防 host 进程 MSVCP140 劫持(修 QQ 切微软拼音崩溃)#287
Conversation
用户反馈:在 Windows 11 切到微软拼音时 QQ (QQEX.exe v9.9.26.44725) 崩 0xc0000005,故障模块 D:\program\QQ\versions\<ver>\resources\app\ MSVCP140.dll @ 偏移 0x13080。 根因(DLL Hell 经典场景): 1. QQ 把私有版本的 MSVCP140.dll 放在 app/ 目录,DLL 搜索顺序优先于系统 2. ctfmon 切微软拼音 → 把所有已注册 TSF DLL 加载进 QQ 进程 3. 我们 OpenLessIme.dll 此前用 MSBuild 默认 RuntimeLibrary(= MultiThreadedDLL,动态链接 MSVCP140.dll/VCRUNTIME140.dll/UCRT) 4. 在 QQ 进程内被绑给 QQ 自带的旧版 MSVCP140 → 调 std::wstring / std::thread / std::mutex 等跑的是 QQ 那份 → ABI 行为漂移 → AV 修复: - vcxproj 4 处 ItemDefinitionGroup(Debug/Release × Win32/x64)显式声明 <RuntimeLibrary>MultiThreaded</RuntimeLibrary>(Release)/ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>(Debug)。 - DLL 自带 CRT 副本,QQ 私有 MSVCP140 劫持不到。 - DLL 体积 +~300 KB;DLL 内部 STL 不能跨边界共享,但我们 IPC 走 named pipe + JSON(C ABI 友好),不受影响。 不动的部分: - TSF 接口本身已是 COM C ABI(vtable + COM-typed 参数),无需改 - 重量级 ASR/LLM/polish 早已在 OpenLess.exe 主进程,DLL 只做 TSF text service hooks + IPC(已合规"组件极简,IPC 通信"原则) QQ 客观脆弱性已整理详细报告(桌面 PDF/DOCX + GitHub issue),用于上报 TSRC:app/ 目录下 MSVCP140 劫持系统 CRT、版本号目录嵌套混乱、无 IME 崩溃隔离机制、CRT 漂移。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80de07851c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;OPENLESSIME_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||
| <ConformanceMode>true</ConformanceMode> | ||
| <LanguageStandard>stdcpp17</LanguageStandard> | ||
| <RuntimeLibrary>MultiThreaded</RuntimeLibrary> |
There was a problem hiding this comment.
Remove DisableThreadLibraryCalls when using /MT
With the Release builds now linked to the static CRT (MultiThreaded), this DLL still calls DisableThreadLibraryCalls(instance) in windows-ime/src/dllmain.cpp; the Win32 API documentation explicitly says not to call DisableThreadLibraryCalls from a DLL linked to the static CRT because the CRT needs thread attach/detach notifications. In host processes that create threads after loading the TSF DLL, suppressing those callbacks can break CRT per-thread initialization/cleanup and reintroduce crashes or leaks in exactly the arbitrary-host-process scenario this change is meant to harden, so remove that call when using /MT (same issue applies to the Win32 Release setting).
Useful? React with 👍 / 👎.
PR Reviewer Guide 🔍(Review updated until commit 901e9df)Here are some key observations to aid the review process:
|
Codex P1 (PR #287):DLL 改用 /MT 静态链接 CRT 后,仍调 DisableThreadLibraryCalls(instance) 会让静态 CRT 拿不到 DLL_THREAD_DETACH 通知,per-thread TLS 初始化/清理断裂 — 在 host 进程(QQ / Office / 微软拼音切换)创建新 input thread 时反而把这次想修的崩溃问题重新引回。 Microsoft 文档 DisableThreadLibraryCalls 备注明确:使用 static CRT 的 DLL 不应禁用 thread library calls。 修复:删除该调用;保留 g_module 缓存。
|
To use Codex here, create an environment for this repo. |
|
Persistent review updated to latest commit 901e9df |
主要修复 ───────── - fix(windows): TSF DLL 静态链接 CRT,防 host 进程(QQ 等)私有 MSVCP140 劫持导致切微软拼音崩溃 0xc0000005(PR #287 + #289 + Codex P1 review)。 - fix(windows): 移除 DisableThreadLibraryCalls — /MT 下 CRT 需要 thread attach/detach 通知做 per-thread TLS 清理,禁用反而触发崩溃。 - fix(recording): 录音条出现时 mic 已 capture,按 Option 不再吞开头 字。emit Recording 加 race 检查避免短按时覆盖 stop/cancel UI 信号。 - fix(startup): splash 透明背景 + 卡片化,避免长启动时左半白屏。 - fix(vault): keyring chunks 用稳定 account name —— macOS Keychain Always-Allow 不再因 UUID 轮换失效;不再每次 load 都尝试删 9 个 legacy entries 触发 ACL 弹窗(与 PR #277 一起)。 新功能 ───────── - feat(security): 凭据从 plaintext JSON 迁移到平台 credential vault (macOS Keychain / Windows Credential Manager / Linux libsecret)。 Windows 2560 byte 限制下用 chunked storage;partial-write safe。 legacy 多源迁移完成后自动清理(PR #277)。 工程 ───────── - chore(ci): 暂时搁置 macos-13(Intel mac)matrix —— GH Actions runner pool 紧张到每次 dispatch queue 1-2h(已观测 4 次)。Apple Silicon 用户 dmg 仍发;Intel mac 用户保留 v1.2.20 dmg + Rosetta 说明(issue #299)。 - chore(devex): CI 加 macOS 矩阵 + 5-way 版本号一致性校验 + scripts/bump-version.sh 一行同步 5 处版本号。.gitignore 加 promo-openless-v2 / node_modules / dist / target 全局兜底(PR #294)。 - docs: docs/audit-2026-05-06.md 工程审计基线,覆盖架构 / UI bug / 多端一致性 / IPC 1:1 校验 / P0/P1/P2 改进路径。 - chore: 9 个改进 issue (#295-#303) 跟踪 audit 列出的所有 P1/P2/P3 问题。
User description
用户反馈
Windows 11 上 QQ (QQEX.exe v9.9.26.44725) 切到微软拼音时崩溃:
```
异常代码:0xc0000005 (STATUS_ACCESS_VIOLATION)
故障模块:D:\program\QQ\versions\\resources\app\MSVCP140.dll
偏移:0x13080
```
根因(DLL Hell)
修复(surgical)
`OpenLessIme.vcxproj` 4 处 `ItemDefinitionGroup` 加 `MultiThreaded(Debug)`:
不动的部分(已合规)
QQ 客观脆弱性(已整理详细报告,用于 TSRC 上报)
Test plan
PR Type
Bug fix, Enhancement
Description
静态链接
OpenLessIme.dll的 CRT避免宿主进程 DLL 劫持崩溃
保留线程库通知用于 CRT 初始化
Diagram Walkthrough
File Walkthrough
dllmain.cpp
Preserve thread notifications for static CRTopenless-all/app/windows-ime/src/dllmain.cpp
DisableThreadLibraryCallsduring process attachOpenLessIme.vcxproj
Switch DLL build to static CRTopenless-all/app/windows-ime/OpenLessIme.vcxproj
RuntimeLibrarytoMultiThreadedDebugfor Debug buildsRuntimeLibrarytoMultiThreadedfor Release buildsWin32andx64configurationsMSVCP140.dllhijacking